package com.zx.fm.controller;

import com.zx.common.annotation.Log;
import com.zx.common.core.controller.BaseController;
import com.zx.common.core.domain.AjaxResult;
import com.zx.common.core.domain.entity.SysRole;
import com.zx.common.core.page.TableDataInfo;
import com.zx.common.enums.BusinessType;
import com.zx.common.utils.aliyunOSS.AliyunOSSConstants;
import com.zx.common.utils.aliyunOSS.AliyunOSSUtil;
import com.zx.common.utils.poi.ExcelUtil;
import com.zx.fm.domain.ReimbursementApplication;
import com.zx.fm.domain.ReimbursementApplicationVO;
import com.zx.fm.service.IReimbursementApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * -- 高贵的马儿驱逐体内的一切外力 --
 *
 * @author kaajee
 * @date 2025/9/1
 * @desc
 */
@RestController
@RequestMapping("/fm/ra")
public class ReimbursementApplicationController extends BaseController {
    @Autowired
    private IReimbursementApplicationService reimbursementApplicationService;

    /**
     * 查询所有报销申请
     */
    @GetMapping("/list")
    public TableDataInfo list(ReimbursementApplicationVO rAVO) {
        startPage();
        List<ReimbursementApplicationVO> list = reimbursementApplicationService.RAlist(rAVO);
        return getDataTable(list);
    }
    @PreAuthorize("@ss.hasPermi('fm:ra:export')")
    @Log(title = "报销管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ReimbursementApplicationVO rAVO) {
        List<ReimbursementApplicationVO> list = reimbursementApplicationService.RAlist(rAVO);
        ExcelUtil<ReimbursementApplicationVO> util = new ExcelUtil<>(ReimbursementApplicationVO.class);
        util.exportExcel(response, list, "报销申请数据");
    }

    /**
     * 根据id查询报销申请
     */
    @GetMapping("/get/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        ReimbursementApplicationVO raVo = reimbursementApplicationService.selectRAById(id);
        raVo.setFileUrl(AliyunOSSConstants.COMMON_URL + raVo.getFileUrl()); // 补充完整文件URL
        return AjaxResult.success(raVo);
    }

    /**
     * 新增报销申请（支持文件上传）
     * 注意：前端需要用 multipart/form-data 格式提交
     */
    @PreAuthorize("@ss.hasPermi('fm:ra:add')")
    @Log(title = "报销管理", businessType = BusinessType.INSERT)
    @PostMapping(value = "/add", consumes = "multipart/form-data")
    public AjaxResult add(
            @Validated @RequestPart("reimbursementApplication") ReimbursementApplication reimbursementApplication,
            @RequestPart(value = "file", required = false) MultipartFile file) {

        try {
            // 处理文件上传（如果有文件）
            if (file != null && !file.isEmpty()) {
                String fileUrl = uploadFileToOSS(file);
                reimbursementApplication.setFileUrl(fileUrl); // 关联文件URL
            }

            // 设置创建人及时间
            reimbursementApplication.setUserId(getUserId());
            reimbursementApplication.setApplicationTime(new Date());

            return toAjax(reimbursementApplicationService.insertRA(reimbursementApplication));
        } catch (Exception e) {
            return AjaxResult.error("新增失败：" + e.getMessage());
        }
    }

    /**
     * 修改报销申请（支持文件上传）
     * 注意：前端需要用 multipart/form-data 格式提交
     */
    @PreAuthorize("@ss.hasPermi('fm:ra:edit')")
    @Log(title = "报销管理", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/edit", consumes = "multipart/form-data")
    public AjaxResult edit(
            @Validated @RequestPart("reimbursementApplication") ReimbursementApplication reimbursementApplication,
            @RequestPart(value = "file", required = false) MultipartFile file) {
        try {
            // 处理文件上传（如果有新文件）
            if (file != null && !file.isEmpty()) {
                // 删除原文件（如果有）
                ReimbursementApplication oldRA = reimbursementApplicationService.selectRAById(reimbursementApplication.getId());
                if (oldRA != null && oldRA.getFileUrl() != null && !oldRA.getFileUrl().isEmpty()) {
                    System.out.println("------OSS文件删除开始--------" + oldRA.getFileUrl());
                    AliyunOSSUtil.delete(oldRA.getFileUrl());  // 删除OSS文件
                }
                String fileUrl = uploadFileToOSS(file);
                System.out.println("fileUrl = " + fileUrl);
                reimbursementApplication.setFileUrl(fileUrl); // 更新文件URL
            } else {
                // 如果没有传新文件，保留原文件URL（从数据库查询原有数据）
                ReimbursementApplication oldRA = reimbursementApplicationService.selectRAById(reimbursementApplication.getId());
                if (oldRA != null) {
                    reimbursementApplication.setFileUrl(oldRA.getFileUrl());
                }
            }

            return toAjax(reimbursementApplicationService.updateRA(reimbursementApplication));
        } catch (Exception e) {
            return AjaxResult.error("修改失败：" + e.getMessage());
        }
    }

    /**
     * 删除报销申请
     * 注意：删除文件时，需要先从OSS删除，再删除数据库记录
     */
    @PreAuthorize("@ss.hasPermi('fm:ra:del')")
    @Log(title = "报销管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/del/{id}")
    public AjaxResult remove(@PathVariable Long id) {
        String fileUrl = reimbursementApplicationService.selectRAById(id).getFileUrl();// 先查询文件URL，再删除OSS文件
        if (fileUrl != null && !fileUrl.isEmpty()) {
            System.out.println("------OSS文件删除开始--------" + fileUrl);
            AliyunOSSUtil.delete(fileUrl);  // 删除OSS文件
        }
        return toAjax(reimbursementApplicationService.deleteRAById(id));
    }

    /**
     * 通用文件上传到OSS的方法
     */
    private String uploadFileToOSS(MultipartFile file) throws Exception {
        String fileUrl = AliyunOSSUtil.upload(file);
        if (fileUrl == null) {
            throw new RuntimeException("文件上传到OSS失败");
        }
        return fileUrl; // 返回OSS文件URL
    }
}
